//
//  GameController.m
//  NuevoMundo
//
//  Created by Bob Rosset on 11/21/10.
//  Copyright 2010 Bob Rosset. All rights reserved.
//

#import "GameController.h"

#define countryName1 @"France"
#define countryName2 @"England"
#define countryName3 @"Spain"
#define countryName4 @"Neatherlands"
#define TOUCH_SIZE 20
#define startX 1539.00
#define startY 1215.00
#define minX 80.00
#define maxX 945.00
#define minY 220.00
#define maxY 710.00
#define firstYear 1492
#define firstSeason 1

#define leftMargin 0
#define rightMargin -(worldMap.contentSize.width - [[CCDirector sharedDirector] winSize].width)
#define topMargin -(worldMap.contentSize.height - [[CCDirector sharedDirector] winSize].height)
#define bottomMargin 0

@implementation GameController

static GameController* instance;

+(id) scene
{
	CCScene *scene = [CCScene node];
	
	GameController *layer = [GameController sharedInstance];
	Map *mapLayer = [Map sharedInstance];
	
	[scene addChild: mapLayer];
	[scene addChild: layer];
	
	return scene;
}


+(GameController*)sharedInstance
{
	@synchronized(self) {
		if (!instance)
			instance = [GameController node];
		return instance;
	}
}

-(id) init
{
	self = [super init];
	if (self != nil) {
		/*** Global Settings ***/
		NSString *path = [[NSBundle mainBundle] pathForResource:@"GlobalSettings" ofType:@"plist"];
		NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
		squareSize = [[dict objectForKey:@"squareSize"] intValue];
		mapWidth = [[dict objectForKey:@"mapWidth"] intValue];
		mapHeight = [[dict objectForKey:@"mapHeight"] intValue];
		/*** Global Settings ***/
		
		self.isTouchEnabled = YES;
		
		worldMap = [Map sharedInstance];
		
		faction = 1;
		
		userUnits		= [[NSMutableArray array] retain];
		movementArray	= [[NSMutableArray array] retain];
		
		/*** ***/
		miniMap			= [CCSprite spriteWithFile:@"miniMap.png"];
		mainFrame		= [CCSprite spriteWithFile:@"mainFrame.png"];
		mapBackground	= [CCSprite spriteWithFile:@"mapBackground.png"];
		displayUnit		= [CCSprite spriteWithFile:@"transparent.png"];
		/*** ***/
		
		year	= firstYear;
		season	= 1;
		
		/*** ***/
		countryLabel	= [CCLabelTTF labelWithString:[NSString stringWithFormat:@"%@",countryName1] dimensions:CGSizeMake(85,20) alignment:UITextAlignmentLeft fontName:@"Arial" fontSize:18];
		seasonLabel		= [CCLabelTTF labelWithString:[NSString stringWithFormat:@"%@, %i",[self getSeason], year] dimensions:CGSizeMake(85,20) alignment:UITextAlignmentLeft fontName:@"Arial" fontSize:12];
		moneyLabel		= [CCLabelTTF labelWithString:@"0"/*[NSString stringWithFormat:@"%@",country]*/ dimensions:CGSizeMake(65,20) alignment:UITextAlignmentLeft fontName:@"Arial" fontSize:12];
		taxLabel		= [CCLabelTTF labelWithString:@"0 %"/*[NSString stringWithFormat:@"%@",country]*/ dimensions:CGSizeMake(65,20) alignment:UITextAlignmentLeft fontName:@"Arial" fontSize:12];
		unitTypeLabel	= [CCLabelTTF labelWithString:@"" dimensions:CGSizeMake(78,20) alignment:UITextAlignmentCenter fontName:@"Arial" fontSize:12];
		movesLabel		= [CCLabelTTF labelWithString:@"" dimensions:CGSizeMake(100,20) alignment:UITextAlignmentLeft fontName:@"Arial" fontSize:12];
		orderLabel		= [CCLabelTTF labelWithString:@""/*[NSString stringWithFormat:@"%@",country]*/ dimensions:CGSizeMake(100,20) alignment:UITextAlignmentLeft fontName:@"Arial" fontSize:12];
		endTurnLabel	= [CCLabelTTF labelWithString:@"Tap to end turn" dimensions:CGSizeMake(100,20) alignment:UITextAlignmentLeft fontName:@"Arial" fontSize:12];
		/*** ***/
		
		[self createInitialUnits];
		
		/*** ***/
		countryLabel.color	= ccc3(219,203,137);
		seasonLabel.color	= ccc3(219,203,137);
		moneyLabel.color	= ccc3(219,203,137);
		taxLabel.color		= ccc3(219,203,137);
		unitTypeLabel.color	= ccc3(219,203,137);
		movesLabel.color	= ccc3(219,203,137);
		orderLabel.color	= ccc3(219,203,137);
		endTurnLabel.color	= ccc3(237,193,12);
		/*** ***/
		
		/*** ***/
		miniMap.position		= ccp(miniMap.contentSize.width/2,miniMap.contentSize.height/2);
		mainFrame.position		= ccp([[CCDirector sharedDirector] winSize].width/2,mainFrame.contentSize.height/2);
		mapBackground.position	= ccp(173,102);
		countryLabel.position	= ccp(385,90);
		seasonLabel.position	= ccp(385,65);
		moneyLabel.position		= ccp(395,33);
		taxLabel.position		= ccp(395,13);
		unitTypeLabel.position	= ccp(473,15);
		movesLabel.position		= ccp(570,83);
		orderLabel.position		= ccp(570,68);
		displayUnit.position	= ccp(473,60);
		endTurnLabel.position	= ccp(980,10);
		/*** ***/
		
		/*** ***/
		[self addChild:miniMap z:110];
		[self addChild:mainFrame z:100];
		[self addChild:mapBackground z:105];
		[self addChild:countryLabel z:110];
		[self addChild:seasonLabel z:110];
		[self addChild:moneyLabel z:110];
		[self addChild:taxLabel z:110];
		[self addChild:unitTypeLabel z:110];
		[self addChild:movesLabel z:110];
		[self addChild:orderLabel z:110];
		[self addChild:displayUnit z:110];
		[self addChild:endTurnLabel z:110];
		
		for(int i = 0; i < [userUnits count]; i++)
		{
			Unit* unit = [userUnits objectAtIndex:i];
			unit.position = ccp(startX,startY);
			[worldMap addChild:unit.sprite z:305];
		}
		/*** ***/
		
		/*** ***/
		endTurnLabel.visible = NO;
		endTurnAction = [[CCSequence actions:[CCFadeOut actionWithDuration:1.5f],[CCFadeIn actionWithDuration:1.5f],nil] retain];
		/*** ***/
		
		[self schedule: @selector(gameUpdate:)];
		
		instance = self;
	}
	
	return self;
}

-(void) createInitialUnits
{
	WaterUnit* boat;
	WaterUnit* boat2;
	LandUnit* colonist1;
	LandUnit* colonist2;
	switch (faction) {
		case 1:
			boat = [[Galleon alloc] init];
			boat2 = [[Privateer alloc] init];
			colonist1 = [[Lumberjack alloc] init];
			colonist2 = [[Soldier alloc] init];
			break;
		case 2:
			boat = [[Galleon alloc] init];
			boat2 = [[Privateer alloc] init];
			colonist1 = [[Lumberjack alloc] init];
			colonist2 = [[Soldier alloc] init];
			break;
		case 3:
			boat = [[Galleon alloc] init];
			boat2 = [[Privateer alloc] init];
			colonist1 = [[Lumberjack alloc] init];
			colonist2 = [[Soldier alloc] init];
			break;
		case 4:
			boat = [[Galleon alloc] init];
			boat2 = [[Privateer alloc] init];
			colonist1 = [[Lumberjack alloc] init];
			colonist2 = [[Soldier alloc] init];
			break;
		default:
			break;
	}
	
	[userUnits addObject:boat];
	[userUnits addObject:boat2];
	[userUnits addObject:colonist1];
	[userUnits addObject:colonist2];
}

-(void)gameUpdate:(ccTime)dt
{
	endTurn = YES;
		
	if(shouldMoveCurrentUnit) {
		[self moveCurrentUnit];
		[self checkCollision:currentUnit];
	}
	
	for(int i = 0; i < [userUnits count]; i++)
	{
		Unit* unit = [userUnits objectAtIndex:i];
		
		if(unit.movesLeft > 0 && unit.sprite.visible)
			endTurn = NO;
	}
	
	if(endTurn && !endTurnLabel.visible)
		[self showEndTurn];
}

-(void)showEndTurn
{
	endTurnLabel.visible = YES;
	[endTurnLabel runAction:[CCRepeatForever actionWithAction:endTurnAction]];
}

-(void)endTurn
{
	[endTurnLabel stopAllActions];
	endTurnLabel.visible = NO;
	
	season++;
	if(season > 4) {
		season = 1;
		year++;
	}
	
	for(int i = 0; i < [userUnits count]; i++)
	{
		Unit* unit = [userUnits objectAtIndex:i];
		unit.movesLeft = unit.moves;
		
		[self unselect];
	}
	
	[seasonLabel setString:[NSString stringWithFormat:@"%@, %i",[self getSeason], year]];
	
	endTurn = NO;
}

-(void)moveCurrentUnit
{
	if([(NSString*)[movementArray objectAtIndex:0] isEqualToString:@"Right"])
		currentUnit.position = ccp(currentUnit.position.x + squareSize,currentUnit.position.y);
	if([(NSString*)[movementArray objectAtIndex:0] isEqualToString:@"Left"])
		currentUnit.position = ccp(currentUnit.position.x - squareSize,currentUnit.position.y);
	if([(NSString*)[movementArray objectAtIndex:0] isEqualToString:@"Up"])
		currentUnit.position = ccp(currentUnit.position.x,currentUnit.position.y + squareSize);
	if([(NSString*)[movementArray objectAtIndex:0] isEqualToString:@"Down"])
		currentUnit.position = ccp(currentUnit.position.x,currentUnit.position.y - squareSize);
	
	if([(NSString*)[movementArray objectAtIndex:0] isEqualToString:@"Right Up"])
		currentUnit.position = ccp(currentUnit.position.x + squareSize,currentUnit.position.y + squareSize);
	if([(NSString*)[movementArray objectAtIndex:0] isEqualToString:@"Right Down"])
		currentUnit.position = ccp(currentUnit.position.x + squareSize,currentUnit.position.y - squareSize);
	if([(NSString*)[movementArray objectAtIndex:0] isEqualToString:@"Left Up"])
		currentUnit.position = ccp(currentUnit.position.x - squareSize,currentUnit.position.y + squareSize);
	if([(NSString*)[movementArray objectAtIndex:0] isEqualToString:@"Left Down"])
		currentUnit.position = ccp(currentUnit.position.x - squareSize,currentUnit.position.y - squareSize);
	
	currentUnit.movesLeft--;
	
	[movementArray removeObjectAtIndex:0];
	
	[self updateCurrentShowedInfo];
	/*
	if(currentUnit.position.x < minX || currentUnit.position.x > maxX)
		currentUnit.position = ccp(startX,currentUnit.position.y);
	
	if(currentUnit.position.y < minY || currentUnit.position.y > maxY)
		currentUnit.position = ccp(currentUnit.position.x,startY);
	*/
	if([movementArray count] == 0)
		shouldMoveCurrentUnit = NO;
}

-(void)checkCollision:(Unit*)_unit
{
	for(int i = 0; i < [userUnits count]; i++)
	{
		Unit* unit = [userUnits objectAtIndex:i];
		if([_unit isKindOfClass:[LandUnit class]]) {
			if(unit != _unit) {
				if (CGRectIntersectsRect(unit.sprite.boundingBox, _unit.sprite.boundingBox)) {
					if([unit isKindOfClass:[WaterUnit class]]) {
						[(LandUnit*)_unit setShippedTo:unit];
						_unit.sprite.visible = NO;
						
						[[unit cargo] addObject:_unit];
					}
				}
			}
		}
	}
}

-(void)setSelected:(Unit*)_unit
{
	[unitTypeLabel setString:[NSString stringWithFormat:@"%@",_unit.unitName]];
	[movesLabel setString:[NSString stringWithFormat:@"Moves: %i",_unit.movesLeft]];
	[orderLabel setString:[NSString stringWithFormat:@"%@",[self getOrder:_unit.orders]]];
	
	CCSprite* newUnit = _unit.sprite;
	
	shouldMoveCurrentUnit = NO;
	
	CCSpriteFrame* spriteFrame = [CCSpriteFrame frameWithTexture:newUnit.texture rectInPixels:newUnit.textureRect rotated:NO offset:newUnit.offsetPositionInPixels originalSize:newUnit.textureRect.size];
	[displayUnit setDisplayFrame:spriteFrame];
	
	currentUnit = _unit;
}

-(void)unselect
{
	[unitTypeLabel setString:@""];
	[movesLabel setString:@""];
	[orderLabel setString:@""];
	
	CCSprite* newUnit = [CCSprite spriteWithFile:@"transparent.png"];
	
	shouldMoveCurrentUnit = NO;
	
	CCSpriteFrame* spriteFrame = [CCSpriteFrame frameWithTexture:newUnit.texture rectInPixels:newUnit.textureRect rotated:NO offset:newUnit.offsetPositionInPixels originalSize:newUnit.textureRect.size];
	[displayUnit setDisplayFrame:spriteFrame];
	
	currentUnit = NULL;
}

-(void)updateCurrentShowedInfo
{
	[movesLabel setString:[NSString stringWithFormat:@"Moves: %i",currentUnit.movesLeft]];
	[orderLabel setString:[NSString stringWithFormat:@"%@",[self getOrder:currentUnit.orders]]];
}

-(void)showMultipleUnits
{
	hidePopUp = NO;
	[self displayPopUp:YES];
}

-(void)hideMultipleUnits
{
	hidePopUp = YES;
}

-(void)displayPopUp:(BOOL)_display
{
	if(_display) {
		popup = [[PopUp alloc]initAsMultipleUnits];
		[self addChild:popup.sprite z:400];
	} else {
		[self removeChild:popup.sprite cleanup:YES];
		[popup release];
		popup = nil;
	}
}

-(NSString*)getSeason
{
	NSString* returnText;
	
	switch (season) {
		case 1:
			returnText = @"Summer";
			break;
		case 2:
			returnText = @"Autumn";
			break;
		case 3:
			returnText = @"Winter";
			break;
		case 4:
			returnText = @"Spring";
			break;
		default:
			returnText = @"";
			break;
	}
	
	return returnText;
}

-(NSString*)getOrder:(int)_order
{
	NSString* returnText;
	
	switch (_order) {
		case 0:
			returnText = @"No Orders";
			break;
		case 1:
			returnText = @"Sentry";
			break;
		case 2:
			returnText = @"Fortified";
			break;
		case 3:
			returnText = @"Jerking";
			break;
		default:
			returnText = @"";
			break;
	}
	
	return returnText;
}

-(void)checkBounds
{
	float xAxis = worldMap.position.x;
	float yAxis = worldMap.position.y;
	
	if(worldMap.position.x > leftMargin) {
		xAxis = leftMargin;
	} else if(worldMap.position.x < rightMargin) {
		xAxis = rightMargin;
	}
	
	if(worldMap.position.y > bottomMargin) {
		yAxis = bottomMargin;
	} else if(worldMap.position.y < topMargin) {
		yAxis = topMargin;
	}
	
	[worldMap runAction:[CCMoveTo actionWithDuration:0.3 position:ccp(xAxis,yAxis)]];
}

-(void)drawSquare
{
}

-(BOOL)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
	UITouch *touch = [touches anyObject];
	CGPoint location = [touch locationInView: [touch view]];
	CGPoint coords = [[CCDirector sharedDirector] convertToGL:location];
	CGRect touchingBox = CGRectMake(coords.x - TOUCH_SIZE / 2, coords.y - TOUCH_SIZE / 2, TOUCH_SIZE, TOUCH_SIZE);
	
	dragTouchPosition = coords;
	
	if(CGRectIntersectsRect(touchingBox, endTurnLabel.boundingBox)) {
		[self endTurn];
		return YES;
	}
	
	touchingBox = CGRectMake((coords.x + (worldMap.position.x * -1)) - TOUCH_SIZE / 2, (coords.y + (worldMap.position.y * -1)) - TOUCH_SIZE / 2, TOUCH_SIZE, TOUCH_SIZE);
	
	if(!popup) {
		for(int i = 0; i < [userUnits count]; i++)
		{
			Unit* unit = [userUnits objectAtIndex:i];
			
			if(unit.sprite.visible) {
				if (CGRectIntersectsRect(touchingBox, unit.sprite.boundingBox)) {
					
					if(touch.tapCount == 2) {
						if([unit isKindOfClass:[WaterUnit class]])
							if([[unit cargo] count] > 0)
								[self showMultipleUnits];
					}
					
					[self setSelected:unit];
					return YES;
				}
			}
		}
		
		[self unselect];
	} else {
		if (!CGRectIntersectsRect(touchingBox, popup.sprite.boundingBox)) {
			[self hideMultipleUnits];
		}
	}

	return YES;
}

-(BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
	if(!hidePopUp && !popup) {
		UITouch *touch = [touches anyObject];
		CGPoint location = [touch locationInView: [touch view]];
		CGPoint coords = [[CCDirector sharedDirector] convertToGL:location];
		
		if(currentUnit) {
			
			if(currentUnit.movesLeft > 0) {
				
				coords.x = (coords.x + (worldMap.position.x * -1));
				coords.y = (coords.y + (worldMap.position.y * -1));
			
				NSString* direction = @"";
				
				CGPoint movementPosition = currentUnit.position;
				
				for(int i = 0;i < [movementArray count];i++) {
					if([(NSString*)[movementArray objectAtIndex:i] isEqualToString:@"Right"])
						movementPosition = ccp(movementPosition.x + squareSize,movementPosition.y);
					if([(NSString*)[movementArray objectAtIndex:i] isEqualToString:@"Left"])
						movementPosition = ccp(movementPosition.x - squareSize,movementPosition.y);
					if([(NSString*)[movementArray objectAtIndex:i] isEqualToString:@"Up"])
						movementPosition = ccp(movementPosition.x,movementPosition.y + squareSize);
					if([(NSString*)[movementArray objectAtIndex:i] isEqualToString:@"Down"])
						movementPosition = ccp(movementPosition.x,movementPosition.y - squareSize);
					
					if([(NSString*)[movementArray objectAtIndex:i] isEqualToString:@"Right Up"])
						movementPosition = ccp(movementPosition.x + squareSize,movementPosition.y + squareSize);
					if([(NSString*)[movementArray objectAtIndex:i] isEqualToString:@"Right Down"])
						movementPosition = ccp(movementPosition.x + squareSize,movementPosition.y - squareSize);
					if([(NSString*)[movementArray objectAtIndex:i] isEqualToString:@"Left Up"])
						movementPosition = ccp(movementPosition.x - squareSize,movementPosition.y + squareSize);
					if([(NSString*)[movementArray objectAtIndex:i] isEqualToString:@"Left Down"])
						movementPosition = ccp(movementPosition.x - squareSize,movementPosition.y - squareSize);
				}
				
				if(coords.x > (movementPosition.x + squareSize/1.5)) {
					//Right
					direction = @"Right";
					if(coords.y > (movementPosition.y + squareSize/2)) {
						//Right Up
						direction = @"Right Up";
					}
					
					if(coords.y < (movementPosition.y - squareSize/2)) {
						//Right Down
						direction = @"Right Down";
					}
				}
				
				if(coords.x < (movementPosition.x - squareSize/1.5)) {
					//Left
					direction = @"Left";
					if(coords.y > (movementPosition.y + squareSize/2)) {
						//Left Up
						direction = @"Left Up";
					}
					
					if(coords.y < (movementPosition.y - squareSize/2)) {
						//Left Down
						direction = @"Left Down";
					}
				}
				
				if(coords.y > (movementPosition.y + squareSize/1.5)) {
					//Up
					direction = @"Up";
					if(coords.x > (movementPosition.x + squareSize/2)) {
						//Right Up
						direction = @"Right Up";
					}
					
					if(coords.x < (movementPosition.x - squareSize/2)) {
						//Left Up
						direction = @"Left Up";
					}
				}
				
				if(coords.y < (movementPosition.y - squareSize/1.5)) {
					//Down
					direction = @"Down";
					if(coords.x > (movementPosition.x + squareSize/2)) {
						//Right Up
						direction = @"Right Down";
					}
					
					if(coords.x < (movementPosition.x - squareSize/2)) {
						//Left Up
						direction = @"Left Down";
					}
				}
				
				if(![direction isEqualToString:@""]) {
					if([movementArray count] < currentUnit.movesLeft) {
						[movementArray addObject:direction];
						//[self drawSquare];
					}
					//NSLog(@"%@",direction);
				}
				
			}
			
		} else {
			worldMap.position = ccp(worldMap.position.x - (dragTouchPosition.x-coords.x),worldMap.position.y - (dragTouchPosition.y-coords.y));
			dragTouchPosition = coords;
		}
		
	}
	
	return YES;
}

-(BOOL)ccTouchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
	if(!hidePopUp) {
		if(currentUnit) {
			if([movementArray count] > 0) {
				shouldMoveCurrentUnit = YES;
			}
		}
	} else {
		[self displayPopUp:NO];
		hidePopUp = NO;
	}
	
	[self checkBounds];

	return YES;
}

- (void)dealloc {
	[userUnits removeAllObjects];
	[userUnits release];
	
	[movementArray removeAllObjects];
	[movementArray release];
	
	[endTurnAction release];
	
	[super dealloc];
}

@end
